package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.apis.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.exception.CustomException;
import com.heima.common.tess4j.Tess4jClient;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author CC
 * time 2024-05-07
 * description
 */
@Transactional
@Slf4j
@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private WmChannelMapper wmChannelMapper;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;
    @Autowired
    private Tess4jClient tess4jClient;

    /**
     * 全局事务处理：解决异步调用时，文章微服务出现异常时无法回滚自媒体微服务
     * @param id
     */
    @Override
    @Async
    @GlobalTransactional
    public void autoScanWmNews(Integer id) {
        if (id==null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews news = wmNewsMapper.selectById(id);
        if (news == null) {
            throw new RuntimeException("WmNewsAutoScanServiceImpl 文章不存在");
        }
        //非审核状态
        if (!news.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
            return;
        }
        //提取内容和图片(内容图片，封面图片)
        String content = news.getContent();
        List<String> contentImgs = new ArrayList<>();
        String text = "";
        if (StringUtils.hasText(content)) {
            StringBuilder builder = new StringBuilder();
            List<Map> maps = JSONArray.parseArray(content, Map.class);
            for (Map map : maps) {
                if ("image".equals(map.get("image"))) {
                    contentImgs.add(String.valueOf(map.get("value")));
                }
                if("text".equals(map.get("text"))){
                    builder.append(map.get("text"));
                }
            }
            String images = news.getImages();
            if (StringUtils.hasText(images)) {
                Arrays.stream(images.split(",")).forEach(contentImgs::add);
            }
            text=builder.toString();
        }
        //审核文本内容
        List<String> collect = wmSensitiveMapper.selectList(Wrappers.
                lambdaQuery(WmSensitive.class)
                .select(WmSensitive::getSensitives)).
                stream().map(WmSensitive::getSensitives).
                collect(Collectors.toList());
        SensitiveWordUtil.initMap(collect);
        //标记审核状态,默认审核成功
        boolean reviewStatus=true;
        try{
            if (StringUtils.hasText(text)) {
                Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(news.getTitle()+text);
                if (!CollectionUtils.isEmpty(stringIntegerMap)) {
                    reviewStatus=false;
                    news.setReason("当前文章存在违规内容");
                    news.setStatus(((short) 2));
                    wmNewsMapper.updateById(news);
                }
                //随机审核失败 或 人工审核
//                short floor = (short) Math.floor(Math.random() * 2 + 2);
//                news.setStatus((floor));
//                reviewStatus = false;
//                news.setReason(floor==3?"当前文章存在不确定元素,需进一步审核":"当前文章存在违规内容");
//                wmNewsMapper.updateById(news);
                //以下采用付费审核
//                Map map = greenTextScan.greeTextScan(news.getTitle().concat("-")+text);
//                if (map!=null&&!map.isEmpty()){
//                    Object suggestion = map.get("suggestion");
//                    if ("block".equals(suggestion)) {
//                        reviewStatus=false;
//                        news.setStatus(((short) 2));
//                        news.setReason("当前文章存在违规内容");
//                        wmNewsMapper.updateById(news);
//                    }
//                    if ("review".equals(suggestion)){
//                        reviewStatus=false;
//                        //进入待人工介入的审核
//                        news.setStatus(((short) 3));
//                        news.setReason("当前文章存在不确定元素,需进一步审核");
//                        wmNewsMapper.updateById(news);
//                    }
//                }
            }

        } catch (Exception e) {
            log.error("审核文本内容失败",e);
            reviewStatus=false;
        }
        //审核失败则退出
        if(!reviewStatus)return;

        //审核图片
        boolean reviewImgStatus = true;

        try {
            if(!CollectionUtils.isEmpty(contentImgs)){
                List<byte[]> bytes=new ArrayList<>();
                contentImgs=contentImgs.stream().distinct().collect(Collectors.toList());
                for (String contentImg : contentImgs) {
                    byte[] bytes1 = fileStorageService.downLoadFile(contentImg);
                    ByteArrayInputStream bi = new ByteArrayInputStream(bytes1);
                    BufferedImage read = ImageIO.read(bi);
                    String s = tess4jClient.doOCR(read);
                    Map<String, Integer> s1 = SensitiveWordUtil.matchWords(s);
                    if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(s1)) {
                        reviewStatus=false;
                        break;
                    }
                    bytes.add(bytes1);
                }
                //随机审核失败 或 人工审核
//                short floor = (short) Math.floor(Math.random() * 2 + 2);
//                news.setStatus((floor));
//                reviewStatus = false;
//                news.setReason(floor==3?"当前文章存在不确定元素,需进一步审核":"当前文章存在违规内容");
//                wmNewsMapper.updateById(news);
                //以下采用付费审核
//                Map map = greenImageScan.imageScan(contentImgs.stream().distinct().map(fileStorageService::downLoadFile).collect(Collectors.toList()));
//                if (map!=null&&!map.isEmpty()){
//                    Object suggestion = map.get("suggestion");
//                    if ("block".equals(suggestion)) {
//                        reviewImgStatus=false;
//                        news.setStatus(((short) 2));
//                        news.setReason("当前文章存在违规内容");
//                        wmNewsMapper.updateById(news);
//                    }
//                    if ("review".equals(suggestion)){
//                        reviewImgStatus=false;
//                        //进入待人工介入的审核
//                        news.setStatus(((short) 3));
//                        news.setReason("当前文章存在不确定元素,需进一步审核");
//                        wmNewsMapper.updateById(news);
//                    }
//                }
            }
        } catch (Exception e) {
            log.error("审核图片失败",e);
            reviewImgStatus=false;
        }
        if(!reviewImgStatus)return;
        //审核成功,保存APP端相关文章数据
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(news,articleDto);
        articleDto.setLayout(news.getType());
        Integer channelId = news.getChannelId();
        WmChannel wmChannel = wmChannelMapper.selectById(channelId);
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }
        articleDto.setAuthorId(news.getUserId().longValue());
        WmUser wmUser = wmUserMapper.selectById(news.getUserId());
        if (wmUser != null) {
            articleDto.setAuthorName(wmUser.getName());
        }
        if (news.getArticleId() != null) {
            //审核成功，说明此处不是首次审核通过的文章
            articleDto.setId(news.getArticleId());
        }
        articleDto.setCreatedTime(new Date());
        //保存APP端相关数据
        ResponseResult responseResult = iArticleClient.saveArticle(articleDto);
        if (!responseResult.getCode().equals(200)) {
            throw new RuntimeException("文章审核, 保存app端相关数据失败");
        }
        //回填审核通过的id
        news.setArticleId(((Long) responseResult.getData()));
        news.setStatus(((short) 9));
        news.setReason("审核通过");
        wmNewsMapper.updateById(news);
    }
}
